#ifndef OPENCL_H
#define OPENCL_H

#include <vector>
#include <CL/cl.hpp>
#include <QObject>
#include <exception>
#include "openclexception.h"

#include "global_flag.h"

/// Parallel transformation class
class OpenCL : public QObject
{
    Q_OBJECT

    std::vector<cl::Platform> _platforms;
    std::vector<cl::Device> _devices;
    cl::Platform _defaultPlatform;
    cl::Device _defaultDevice;
    cl::Context* _context;
    std::string _kernelCode;
    cl::Buffer* _imageBuffer;
    cl::Buffer* _resultBuffer;
    cl::Buffer* _filterBuffer;
    cl::CommandQueue* _queue;
    cl::Program* _program;
    cl::Kernel* _imgProcess;

    int _imageWidth;
    int _imageHeight;
    int _filterSize;
    float _bias;
    float _factor;

//exceptions
     cl_int _error;

    /*std::runtime_error _kernelFileException;
    std::runtime_error _clCommandQueueException;
    std::runtime_error _clBuildException;
    std::runtime_error _clEnqueueException;
    std::runtime_error _clFinishException;
    std::runtime_error _clReadException;*/

public:
    OpenCL(const cl::Platform platform, const cl::Device device);
    ~OpenCL();
    void set_image_buffer(int* data, const int width, const int height);
    void set_filter_buffer(float* data, const int size);
    void set_bias(const float bias);
    void set_factor(const float factor);
    int* run_kernel();

    int* _result; //To free from filter

signals:
    void progress(int);
};

#endif // OPENCL_H
